from typing import Optional, List, Any
from sqlmodel import Field, Relationship, SQLModel
from sqlalchemy import event, JSON, Column
from enum import Enum

from models.Base import BaseAndTime, StatusTypeEnum
from models.common import get_current_time

class assignParams(SQLModel):
    id: int = Field(title='角色组ID')
    ruleIds: List[int] = Field(title='菜单ID列表')

class Game_Group_Rule_Link(SQLModel, table=True):
    __tablename__ = "game_group_rule_link"  
    group_id: Optional[int] = Field(default=None, foreign_key="game_user_group.id", primary_key=True)
    rule_id: Optional[int] = Field(default=None, foreign_key="game_user_rule.id", primary_key=True)

class MenuTypeEnum(Enum):
    MENU = 0
    BUTTON = 1

# 显示链接选项
class ShowLinkEnum(Enum):
    SHOW = True
    HIDE = False

# 固定标签选项
class FixedTagEnum(Enum):
    FIXED = True
    NOT_FIXED = False

# 缓存选项
class KeepAliveEnum(Enum):
    CACHE = True
    NO_CACHE = False

# 隐藏标签选项
class HiddenTagEnum(Enum):
    ALLOW = False
    FORBID = True

# 显示父级菜单选项
class ShowParentEnum(Enum):
    SHOW = True
    HIDE = False

# 框架加载选项
class FrameLoadingEnum(Enum):
    ENABLED = True
    DISABLED = False

# 用户组规则
class Game_User_Create_Rule(SQLModel):
    menu_type: MenuTypeEnum = Field(default=MenuTypeEnum.MENU, sa_column_kwargs={"nullable": False})
    parent_id: int = Field(default=0, sa_column_kwargs={"nullable": False})
    title: str = Field(default="", max_length=100)
    name: str = Field(default="", max_length=100)
    path: str = Field(default="", max_length=255)
    component: Optional[str] = Field(default="", max_length=255)
    rank: int = Field(default=0)
    redirect: Optional[str] = Field(default="", max_length=255)
    icon: Optional[str] = Field(default="", max_length=255)
    extra_icon: Optional[str] = Field(default="", max_length=255)
    enter_transition: Optional[str] = Field(default="", max_length=255)
    leave_transition: Optional[str] = Field(default="", max_length=255)
    active_path: Optional[str] = Field(default="", max_length=255)
    auths: Optional[str] = Field(default="", max_length=100, index=True)
    frame_src: Optional[str] = Field(default="", max_length=255)
    frame_loading: FrameLoadingEnum = Field(default=FrameLoadingEnum.ENABLED, sa_column_kwargs={"nullable": False})
    keep_alive: KeepAliveEnum = Field(default=KeepAliveEnum.NO_CACHE, sa_column_kwargs={"nullable": False})
    hidden_tag: HiddenTagEnum = Field(default=HiddenTagEnum.ALLOW, sa_column_kwargs={"nullable": False})
    fixed_tag: FixedTagEnum = Field(default=FixedTagEnum.NOT_FIXED, sa_column_kwargs={"nullable": False})
    show_link: ShowLinkEnum = Field(default=ShowLinkEnum.SHOW, sa_column_kwargs={"nullable": False})
    show_parent: ShowParentEnum = Field(default=ShowParentEnum.HIDE, sa_column_kwargs={"nullable": False})

class Game_User_Edit_Rule(Game_User_Create_Rule):
    id: int = Field(title='菜单ID')

class Game_User_Rule(BaseAndTime,Game_User_Edit_Rule, table=True):
    __tablename__ = "game_user_rule"  
    higher_menu_options: List[Any] = Field(sa_column=Column(JSON), default=[])
    groups: List["Game_User_Group"] = Relationship(back_populates="rules", link_model=Game_Group_Rule_Link)

    @property
    def menu_type_text(self)->str:
        if self.menu_type == MenuTypeEnum.MENU:
            return "菜单"
        elif self.menu_type == MenuTypeEnum.BUTTON:
            return "按钮"
        return "未知"
    
    @property
    def show_link_text(self)->str:
        if self.show_link == ShowLinkEnum.SHOW:
            return "显示"
        elif self.show_link == ShowLinkEnum.HIDE:
            return "隐藏"
        return "未知"
    
    @property
    def fixed_tag_text(self)->str:
        if self.fixed_tag == FixedTagEnum.FIXED:
            return "固定"
        elif self.fixed_tag == FixedTagEnum.NOT_FIXED:
            return "不固定"
        return "未知"
    
    @property
    def keep_alive_text(self)->str:
        if self.keep_alive == KeepAliveEnum.CACHE:
            return "缓存"
        elif self.keep_alive == KeepAliveEnum.NO_CACHE:
            return "不缓存"
        return "未知"
    
    @property
    def hidden_tag_text(self)->str:
        if self.hidden_tag == HiddenTagEnum.ALLOW:
            return "允许"
        elif self.hidden_tag == HiddenTagEnum.FORBID:
            return "禁止"
        return "未知"
    
    @property
    def show_parent_text(self)->str:
        if self.show_parent == ShowParentEnum.SHOW:
            return "显示"
        elif self.show_parent == ShowParentEnum.HIDE:
            return "隐藏"
        return "未知"
    
    @property
    def frame_loading_text(self)->str:
        if self.frame_loading == FrameLoadingEnum.ENABLED:
            return "启用"
        elif self.frame_loading == FrameLoadingEnum.DISABLED:
            return "禁用"
        return "未知"

@event.listens_for(Game_User_Rule, 'before_update', propagate=True)
def timestamp_before_update(mapper, connection, target):
    target.updatetime = get_current_time()



# 创建用户组
class Game_User_Create_Group(SQLModel):
    name: str = Field(max_length=30,nullable=False,title='角色名字')
    code: str = Field(max_length=30,nullable=False,title='角色编码', unique=True)
    remark: str = Field(max_length=255,nullable=False,title='备注')
    status: StatusTypeEnum = Field(default=StatusTypeEnum.NORMAL,title='状态', index=True)
    parent_id: int = Field(default=None,nullable=False,index=True,title='父级ID')

# 用户组
class Game_User_Group(BaseAndTime, Game_User_Create_Group, table=True):
    __tablename__ = "game_user_group"  # 确保表名一致
    rules: List["Game_User_Rule"] = Relationship(back_populates="groups", link_model=Game_Group_Rule_Link)
    users: List["Game_User"] = Relationship(back_populates="group")
    # users: List["Game_User"] = Relationship(back_populates="groups", link_model=Game_Group_User_Link)
    
    @property
    def status_text(self)->str:
        if self.status == StatusTypeEnum.NORMAL:
            return "正常"
        elif self.status == StatusTypeEnum.ABNORMAL:
            return "关闭"
        return "未知"

@event.listens_for(Game_User_Group, 'before_update', propagate=True)
def timestamp_before_update(mapper, connection, target):
    target.updatetime = get_current_time()


class SexEnum(int, Enum):
    MAN = 0
    WUMEN = 1


class Game_User_Create(SQLModel):
    username: str = Field(max_length=32, default='', title='用户名')
    nickname: str = Field(max_length=50, default='', title='昵称')
    password: str = Field(max_length=100, default='', title='密码')
    email: str = Field(max_length=100, default='', title='电子邮箱')
    mobile: str = Field(max_length=255, default='', title='手机号')
    avatar: str = Field(max_length=255, default='', title='头像')
    level: int = Field(default=0, title='等级')
    gender: SexEnum = Field(sa_column_kwargs={"nullable": False},default=SexEnum.MAN, title='性别', index=True,description="0:男 1:女")
    birthday: Optional[str] = Field(default=None, title='生日')
    bio: str = Field(max_length=100, default='', title='格言')
    money: float = Field(default=0.00, title='余额')
    score: int = Field(default=0, title='积分')
    status: StatusTypeEnum = Field(default=StatusTypeEnum.NORMAL,title='状态', index=True)
    group_id: int | None = Field(default=1, foreign_key="game_user_group.id")
    successions: Optional[int] = Field(default=1, title='连续登录天数')
    maxsuccessions: Optional[int] = Field(default=1, title='最大连续登录天数')
    prevtime: Optional[str] = Field(default=None, title='上次登录时间')
    loginip: Optional[str] = Field(max_length=50, default='', title='登录IP')
    loginfailure: Optional[int] = Field(default=0, title='失败次数')
    joinip: Optional[str] = Field(max_length=50, default='', title='加入IP')
    jointime: Optional[str] = Field(default=None, title='加入时间')

class Game_User_Edit(Game_User_Create):
    id: int = Field(title='用户ID')


# 用户类型：默认，第三方
class UserType(int, Enum):
    DEFAULT = 0
    THIRD_PARTY = 1

# 用户
class Game_User(BaseAndTime, table=True):
    __tablename__ = 'game_user'
    # groups: List["Game_User_Group"] = Relationship(back_populates="users", link_model=Game_Group_User_Link)
    logintime: Optional[int] = Field(default=None, title='登录时间')
    username: str = Field(max_length=32, default='', title='用户名')
    nickname: str = Field(max_length=50, default='', title='昵称')
    password: str = Field(max_length=100, default='', title='密码')
    email: str = Field(max_length=100, default='', title='电子邮箱')
    mobile: str = Field(max_length=255, default='', title='手机号')
    avatar: str = Field(max_length=255, default='', title='头像')
    level: int = Field(default=0, title='等级')
    gender: SexEnum = Field(sa_column_kwargs={"nullable": False},default=SexEnum.MAN, title='性别', index=True,description="0:男 1:女")
    birthday: Optional[int] = Field(default=None, title='生日')
    bio: str = Field(max_length=100, default='', title='格言')
    money: float = Field(default=0.00, title='余额')
    score: int = Field(default=0, title='积分')
    status: StatusTypeEnum = Field(default=StatusTypeEnum.NORMAL,title='状态', index=True)
    group_id: int | None = Field(default=1, foreign_key="game_user_group.id")
    group: Optional["Game_User_Group"] = Relationship(back_populates="users")
    type: UserType = Field(default=UserType.DEFAULT, title='用户类型', index=True)
    successions: Optional[int] = Field(default=1, title='连续登录天数')
    maxsuccessions: Optional[int] = Field(default=1, title='最大连续登录天数')
    prevtime: Optional[int] = Field(default=None, title='上次登录时间')
    loginip: Optional[str] = Field(max_length=50, default='', title='登录IP')
    loginfailure: Optional[int] = Field(default=0, title='失败次数')
    joinip: Optional[str] = Field(max_length=50, default='', title='加入IP')
    jointime: Optional[int] = Field(default=None, title='加入时间')

@event.listens_for(Game_User, 'before_update', propagate=True)
def timestamp_before_update(mapper, connection, target):
    target.updatetime = get_current_time()
class redis_user(SQLModel):
    id: int
    nickname: str
    username: str
    group_id: int
    gender: SexEnum
    bio: str
    money: float
    score: int
    level: int
    mobile: str
    third_user: Optional[dict]



